home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Report Writers / Crystal Repot 9.0 Full CD version / Setup.exe / SRC / HOARDDLL.ZIP / 3rdParty / hoard / libhoard-2.0.2 / privateheap.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-15  |  4.1 KB  |  167 lines

  1. #include <limits.h>
  2. #include <string.h>
  3. #include <new.h>
  4.  
  5.  
  6. #include "config.h"
  7.  
  8. #include "arch-specific.h"
  9. #include "heap.h"
  10.  
  11. #include "privateheap.h"
  12. #include "processheap.h"
  13.  
  14.  
  15. privateHeap::privateHeap (void)
  16.   : _arena (0),
  17.     _arenaRemaining (0)
  18. {
  19.   for (int i = 0; i < hoardHeap::SIZE_CLASSES; i++) {
  20.     _blocks[i] = 0;
  21.   }
  22. }
  23.  
  24.  
  25. // malloc (sz):
  26. //   inputs: the size of the object to be allocated.
  27. //   returns: a pointer to an object of the appropriate size.
  28.  
  29. void * privateHeap::malloc (const size_t size)
  30. {
  31.  
  32.   block * b = 0;
  33.   block * leftOver = 0;
  34.   size_t sz = (size == 0) ? 1 : size;
  35.  
  36.   const int sizeclass = sizeClass (sz);
  37.  
  38.   // Determine the actual size of the block.
  39.   size_t actualSize = hoardHeap::sizeFromClass (sizeclass);
  40.   assert (actualSize >= sz);
  41.  
  42.   // Determine the size to allocate (block header + actual size).
  43.   int allocateSize = hoardHeap::align (sizeof(block) + actualSize);
  44.   assert ((allocateSize & hoardHeap::ALIGNMENT_MASK) == 0);
  45.  
  46.   lock();
  47.  
  48.   if (_blocks[sizeclass]) {
  49.     // We had a block on our free list.
  50.     b = _blocks[sizeclass];
  51.     _blocks[sizeclass] = b->getNext();
  52.   } else {
  53.     // We don't have a free block for this size.
  54.     // See if we have memory left in the arena.
  55.     if (_arenaRemaining < allocateSize) {
  56.       // Not enough.
  57.       // Put the remaining arena onto a free list
  58.       // and then make a new one.
  59.       // (If there's enough room left to make a block.)
  60.       if (_arenaRemaining > sizeof(block) + sizeFromClass(0)) {
  61.     leftOver = new (_arena) block (NULL);
  62.     _arenaRemaining -= sizeof(block);
  63.     
  64.     // Put it into the right class (not too big!)
  65.     int leftOverClass = sizeClass (_arenaRemaining);
  66.     while (sizeFromClass (leftOverClass) > _arenaRemaining) {
  67.       leftOverClass--;
  68.     }
  69.     
  70.     assert (sizeFromClass (leftOverClass) <= _arenaRemaining);
  71.     
  72.     leftOver->setActualSize (sizeFromClass (leftOverClass));
  73.     leftOver->markAllocated();
  74.     
  75. #if HEAP_FRAG_STATS
  76.     leftOver->setRequestedSize (0);
  77. #endif
  78.       }
  79.       // Make a new arena.
  80.       _arena = (void *) hoardSbrk (MAX (allocateSize, HEAP_REFILL_SIZE));
  81.       _arenaRemaining = MAX (allocateSize, HEAP_REFILL_SIZE);
  82.       
  83. #if HEAP_FRAG_STATS
  84.       pHeap->setAllocated (0, _arenaRemaining);
  85. #endif
  86.       if (_arena == (void *) -1) {
  87.     // There is no memory left!
  88.     unlock();
  89.     return 0;
  90.       }
  91.       
  92.       // Align the new arena.
  93.       char * oldarena = (char *) _arena;
  94.       _arena = (char *) hoardHeap::align ((unsigned int) _arena);
  95.       _arenaRemaining = _arenaRemaining - (int) ((char *) _arena - oldarena);
  96.       assert ((((unsigned int) _arena) & hoardHeap::ALIGNMENT_MASK) == 0);
  97.     }
  98.  
  99.     assert (!b);
  100.     assert ((((unsigned int) _arena) & hoardHeap::ALIGNMENT_MASK) == 0);
  101.     assert (_arenaRemaining >= sizeof(block));
  102.     
  103.     // Carve out b from the arena.
  104.     b = new (_arena) block (NULL);
  105.     _arena = (void *) ((char *) _arena + allocateSize);
  106.     _arenaRemaining -= allocateSize;
  107.   }
  108.  
  109.   assert (b);
  110.  
  111.   b->markAllocated();
  112.   b->setActualSize (actualSize);
  113.  
  114. #if HEAP_FRAG_STATS
  115.   b->setRequestedSize (align(size));
  116.   pHeap->setAllocated (align(size), 0);
  117. #endif
  118.  
  119.   // Skip past the block header,
  120.   // and return the pointer.
  121.   
  122.   unlock();
  123.   assert (b->isValid());
  124.  
  125.   if (leftOver) {
  126.     free ((void *) (leftOver + 1));
  127.   }
  128.  
  129.   return (void *) (b + 1);
  130. }
  131.  
  132.  
  133. // free (ptr, pheap):
  134. //   inputs: a pointer to an object allocated by malloc(), above.
  135. //   side effects: returns the block to the object's superblock;
  136. //                 updates the thread heap's statistics;
  137. //                 may release the superblock to the process heap.
  138.  
  139.  
  140. void privateHeap::free (void * ptr)
  141. {
  142.   if (!ptr) {
  143.     return;
  144.   }
  145.  
  146.   // Find the block corresponding to this ptr.
  147.  
  148.   block * const b = (block *) ptr - 1;
  149.   assert (b->isValid());
  150.   b->markFree();
  151.  
  152.   size_t sz = b->getActualSize();
  153. #if HEAP_FRAG_STATS
  154.   pHeap->setDeallocated (b->getRequestedSize(), 0);
  155. #endif
  156.  
  157.   int sizeclass = hoardHeap::sizeClass (sz);
  158.  
  159.   lock();
  160.  
  161.   // Put b into the appropriate freelist.
  162.   b->setNext (_blocks[sizeclass]);
  163.   _blocks[sizeclass] = b;
  164.  
  165.   unlock();
  166. }
  167.